perm filename F8JUL7[3,ALS] blob sn#292844 filedate 1977-07-07 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00012 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	* General remarks
C00008 00003	* RAM and SCRATCHPAD assignments
C00014 00004	* START
C00019 00005	* RASC  SCRC  EMPTY  CAQ  MPYR
C00024 00006	* FKT  GMEN  RFJN  LFJN  STMV
C00029 00007	* NEXT  FIND  RFJ  LFJ  RBJ  LBJ  JUMT  AFT  MAKE  RARA
C00035 00008	* RFN  LFN  RBN  LBN  NORT
C00038 00009	* SELECT  SELE
C00045 00010	* NORM  FORE
C00047 00011	* EVAL
C00050 00012	* SQIN  SQOU  MVIN 
C00055 ENDMK
C⊗;
* General remarks

We envision three levels of play which are personified by calling them
Robot Tom, Robot Dick and Robot Harry.  Robot Tom will be the weakest
player.  Less reprobation will be implied to the user than if the lowest
level were characterized as for the Beginner, and at the other end, less
undeserved credit will be claimed for the program's degree of
proficiency.  The single letters T, D and H could be used to designate
these players.  Depending upon what is decided as to the amount of
audio and visual text that can be generated, these three levels might be
further identified by calling the lowest level "Helpful Robot Tom", the
next as "Silent Robot Dick" and the highest level as "Mighty Robot Harry",
and the board could be displayed in diffrent colors for the three different
levels.

Under normal circumstances, the details of how these levels are adjusted
would be kept from the player.  He would simply be advised to start by
playing Robot Tom and then if he can beat Robot Tom to try playing Robot
Dick and then finally to try playing Robot Harry.

In fact. it might be well to have Robot Tom be the default setting and to
allow the player the option of starting play immediately either by typing
in a move or by typing the character that tells the machine to play black.
This would simplify the use of the program for the very young child who
could be told by his parent to always play black and to simply enter his
opening move.  Alternately the first question to the user might be "Do you
want to play Black against Robot TOM?", and then a "Y" reply would cause
the board to appear, properly oriented with Black pieces at the bottom.
An "N" reply would then lead to a list of questions, with subsequent
questions so phrased that an affirmative answer will be more likely than
a negative one and will usually lead to a termination of the questioning.

I strongly oppose the asking of too many questions of the inexperienced
user.  Even on a much larger computer and with supposedly expert users
this causes an otherwise very useful program to be shunned.  For example,
rather than asking if the user wants to use the Joy Stick, the program should
assume that he does if one is plugged in and assumes that he does not if
he removes the sticks.

The levels of play would be set by changes to the depth of ply to which
the search would be allowed to go and perhaps by the way that stored moves
would be used.

For the truely expert checker player, there should be a way to set the
play to even higher levels.  Actually, this will not be difficult to do
but unfortunately the playing time may be unduely long, and it probably
would be unwise to let the casual user get into trouble by making these
levels readily available.  The good checker player might welcome this
provision.

The user could be advised of this possibility in the literature supplied
with the cartridge and could be told to write in for information as to how
this is done.  This could be used to generate a list of interested users
for a mailing list.  These people would be prime candidates for other
cartridges and perhaps for a new model of the Video Brain when one is
developed.

It would also be possible to allow the user to set up any initial board
conditions that he choses, (a checker puzzle for example) rather than
having to start each game from scratch.  Even the casual user might like
this feature as it would allow him to stop playing in the middle of a game
and to continue the interrupted game as a later time.  To make this easy
to do the program should be able to list the board condition in standard
checker notation (so the user can copy it) rather than forcing the user to
generate this list himself or forcing him to make a picture of the board.
* RAM and SCRATCHPAD assignments

Tree data will be kept in RAM in blocks of 16 bytes, one for each ply depth.

These data will occupy 256 bytes starting at a location that has a second
address byte of 0.  At the start of a game the first two blocks will be
loaded with the conditions that relate to a game with the machine playing
BLACK.  If the player elects to play BLACK then the board conditions after
his move are loaded into the second block.  Thereafter the second block
will be used as the board to start the tree search and the machines reply
will be returned in the first block.

This arrangement, while not essential, will greatly simplify address
computations during the tree search.

Data within each block will be located as follows:

Bytes		Contents

0 thru 3	ACTIVE pieces
4 thru 7	PASSIVE pieces
8 thru 11	KINGS
12		MOVE byte
13		Dir in 0,1  byte number in 2,3  Mobility in left half
14		Jump flag in bit 0  ACTIVE piece debit in left 7 bits
15		SCORE, ACTIVE's assessment of the value to him of this position

When blocks of data are to be operated on, they are moved from RAM into
the Scratchpad registers 16 thru 31.  The piece debit is given special
treatment, however, since two debits must be carried forward, that for the
active side and that for the passive side.  Since the sides will be
reversed when the SC is put back into RAM, the piece debit in SC is gotten
from the previous block, not the current one from which the rest of the
data is gotten.  The piece debit in SC thus refers to the current passive
side while thAt in RAM refers to the active side.  The debit account in SC
is increased by 1 for each promotion made by the active side and increased
by 2 for each piece captured and 3 for each king captured.  At the start
of each play, the piece debit records for the board record from which the
player moves and the resulting board from which the machine plays will be
normallized by subtracting the smaller value fron both records.

The FIND routine is then entered and at that time all possible moves are
determined, the count of the number of moves is accumulated in SC 2. and
stored back into the current RAM record, leaving the mobility for the
previous board in SC which was moved to RAM from SC earlier and then on
SC where it will be useful should it turn out to be time to stop and
evaluate.  However if the decision is to go further then the value from 2
is also written in byte 13 of the current SC block.

  Scratchpad registers 33 to 36 are used for 
EMPTY as created by code EMPTY with 32 and 37 left blank as guards
After processing the data in SC is moved back to RAM in the next block with
the ACTIVE and PASSIVE pieces reversed in position.

Scratchpad registers 0 thru 8 are normally used as follows:

Register	Usage
0		general purpose
1
2	King move flag during SELECT and MOBILITY during FIND
3	Move byte during generation
4	Byte pointer (bits 2 and 3 from FLAG byte, shifted right by 2)
5	Move direction (bits 0, 1 and 4 from FLAG byte)
6	MOVE bit extracted from MOVE
7	FLAG byte for analysis
8	Color of ACTIVE (0 if Black, H'FF' if White)

Data from RAM is transfered into scratchpad registers 16 thru 31 so that
ACTIVE and PASSIVE havE a LISU addres of 2,whoile KINGS and special data
have a LISU address of 3. The empty squares on the board are computed
fresh each time a board is under study and are stored with a LISU of 4.
* START
*Set up initial boards both in SC and in blocks 0 ans 1
START	LISU	2
	LISL	0
	LI	H'FF'
	LR	I,A		First byte of ACTIVE
	LI	H'F0'
	LR	I,A		Second byte of active
	CLR
	LR	I,A		Part of board with no active pieces
	LR	I,A		Part of board with no active pieces
	LR	I,A		Part of board with no passive pieces
	LR	I,A		Part of board with no passive pieces
	LI	H'F'	
	LR	I,A		byte of PASSIVE
	LI	H'FF'
	LR	I,A		Last byte with Passive pieces
	LISU	3
	LISL	0
	CLR
	LR	I,A		4 king bytes next (all empty)
	LR	I,A
	LR	I,A
	LR	I,A
	LI	H'F0'		The 4 leftmost bits for pieces that can move RF
	LR	I,A		The MOVE byte
	LI	H'74'		Mobility of 7,  byte 1 and the RF direction
	LR	I,A
	CLR			Set piece debit and Jump flag to 0
	LR	I,A
	LI	H'80'		Set score at -128
	LR	I,A
***MUST INSERT STARTING LOCATION FOR TREE DATA
	LI	
	LR	10,A
	CLR		Note: H always points to the start of a block
	LR	7,A	This is used in keeping track of promotions
	LR	11,A
	LR	DC,H
	PI	SCRC	Ready for opponents move if he elects BLACK
	PI	SCRC	Ready for Machine to play BLACK
*Now as for side election or opponents first move
**** H must be set properly as must the COLOR in SC 8
**** H is always changed by multiples of H'10'
**** K can probable be left set for Subroutine CAQ, which is probaply used
more than any one other subroutine and then this routine can be entered by
a PK rather than a PI.  This will save both space and time.

Technique to choose machines first move. 

If the machine is to play black then 7
possible first moves will be available in condensed form and a random
choice is made. Perhaps for the best player, the choice could be
limited to 2 or 3 of the best ones with the prefered ones repeated.
If opponent plays black then there will be stored several, probably
4, replies.

Moves are stored in a highly compressed form.  Since there are seldom more
than 16 possible moves, and certainly many fewer in the opening, 4 bits
are sufficient to specify a move from any given starting location, so
moves can be packed two to the byte.  By having the location of the stored
bytes computable from the number specifying the first move one can, in 7
bytes store 2 replies for each possible first move, or 4 replies in 14
words If space permits one could also store perhaps 2 counter replies each
to these replies, this taking 28 additional words.  This, in effect will
cause the machine to play a different game almost every time, An astute
player can, however, note the machine play, and thus acquire a repertoire
of acceptable opening play.

To make the machine do even better with this limited storage, one might give
more weight to a prefered move by storing it twice with 2 others stored once.
* RASC  SCRC  EMPTY  CAQ  MPYR

*Subroutine to move data from RAM into SC 16 thru 31 with the data for
SC 16 thru 27 coming from the current block, 28 and 29 being set to 0 and
30 and 31 from the previous block with the Jump flag in 30 deleted.

RASC	LR	SC,H
	LISU	2
	LISL	0
	LIS	8
	LR	0,A
	PI	RASL
	LISU	3
	LISL	0
	LIS	4
	LR	0,A
	PI	RASL
	CLR
	LR	I,A		Zero MOVE byte
	LR	I,A		Zero Mobility, byte # and direction info.
	LR	DC,H
	LIS	H'FE'		Back up by 2
	ADC
	LM
	NI	H'FE'		Save piece count portion only
	LR	S,A
	LR	A,7		Was a promotion effected last move?
	NS	7
	BZ	RAS2
	LIS	2		Add 1 (remember displacement)
	AS	S
	LR	I,A
	CLR
	LR	7,A		Reset
	LM			Get score
	LR	I,A
	POP

RASL	LM
	LR	I,A
	DS	0
	BNZ	RASL
	POP

*Subroutine to move 16 bytes from SC 16 thru 31 to RAM direct.
SCRD	LISU	2
	LISL	0
	LIS	8
	LR	0,A
	PI	SCRL
	LISU	3
	LISL	0
	LIS	8
	LR	0,A
	PI	SCRL
	POP

*Subroutine to move 16 bytes from SC 16 thru 31 to RAM, reversing ACTI and PASS
SCRC	LISU	2
	LISL	4
	LIS	4
	LR	0,A
	PI	SCRL
	LISL	0
	LIS	4
	LR	0,A
	PI	SCRL
	LISU	3
	LISL	0
	LIS	8
	LR	0,A
	PI	SCRL
	POP

SCRL	LR	A,I
	ST
	DS	0
	BNZ	SCRL
	POP

*To compute 4 bytes which show the empty squares on the board.
*These are stored in SC 33 thru 36 with SC 32 and SC 37 set to zero as guards.
*Note especially that the EMPTY locations are displaced relative to ACTIVE.
EMPTY	LISU	4
	LISL	0
	CLR
	LR	S,A		Make sure guard byte is empty
	LISU	2		Start with ACTIVE
	LIS	4
	LR	0,A
	BR	EMP3
EMP2	LR	A,SI
	AI	H'2F'		Actually subtracting 17 
	LR	SI,A
EMP3	LR	A,S
	LR	1,A
	LR	A,IS
	AI	4
	LR	SI,A
	LR	A,S
	AS	1
	LR	1,A
	LR	A,SI
	AI	H'D'		Add 13 to get to the correct EMPTY location
	LR	IS,A
	LR	A,1
	COM			Reverse 1's and 0's
	LR	I,A
	DS	0
	BNZ	EMP2
	CLR
	LR	S,A		Upper guard byte
	POP

*Subroutine to count bits in 0 and return count in A
Uses registers 0 and 1
CAQ	CLR
	LR	1,A
	LR	A,0
	BR	CAQ3
CAQ2	DS	1
	AI	H'FF'
	NS	0
	LR	0,A
CAQ3	BNZ	CAQ2
	LR	A,1
	COM
	AI	1		Make it into a true positive number
	POP

*Subroutine to multiply 2 positive binary numbers (the smaller in SC 1 and
the larger in SC 2) by Russian multiplication where the product is not
allowed to exceed 31.  This is used to compute score and a large number is
meaningless.  SC 0 is used to accumulate the product.  This code may be
used at only one place and can probably be written in line at that place
with some saving of space.

MPYR	CLR
	LR	0,A		To accumulate the product
	LR	A,1
	NS	1		To set status
	BR	MPY4
MPY1	NI	1		Is the rightmost bit a 1?
	BZ	MPY2		No
	LR	A,2
	AS	0
	LR	0,A
	CI	H'1E'		Is the product too big?
	BP	MPY2		No
	LI	H'1E'		Set it at 30
 	LR	0,A
	BR	MPY5		and stop
MPY2	LR	A,2
	SL	1
	LR	2,A
MPY3	LR	A,1
	SR	1
	LR	1,A
MPY4	BNZ	MPY1		Product is not complete
MPY5	POP
* FKT  GMEN  RFJN  LFJN  STMV

*Subroutine to limit pieces to KINGS depending on direction and color
FKT	CLR
	AS	8
	BR	FK1
BKT	LR	8		Test sides for backward move
	COM
FK1	BZ	FK2		NORMAL pieces can move
	LISU	3		KINGS only can move
	LR	A,S
	NS	3
	LR	3,A
	BZ	FK3		No RF OR LF moves from this byte
FK2	LR	A,3
	NS	3		To set status
FK3	POP

FJET	LR	A,IS
	AI	2	To next forward EMPTY byte (remember displacement)
	LR	IS,A
BJET	LISU	4
	LR	A,S
	POP

*Subroutine to get byte of ACTIVE pieces
GMEN	LR	A,4
	LR	IS,A
	LISU	2
	LR	A,S
	LR	3,A
	POP

*Subroutine used both by RFJ and RJN
RFJN	LR	A,S
	SL	4
	LR	0,A
	LR	A,IS
	AI	1
	LR	IS,A
	LR	A,S
	SR	4
	SR	1
	AS	0
	NS	3
	LR	3,A		The RFJ or RJ byte
	POP

*Subroutine used both by LFJ and LFN
LFJN	LR	A,S
	SL	4
	SL	1
	LR	0,A
	LR	A,IS
	AI	1
	LR	IS,A
	LR	A,S
	SR	4
	AS	0
	NS	3
	LR	3,A		The LFJ or LFN byte
	POP

*Subroutine used both by LBJ and LBN
LBJN	LR	A,S
	SL	4
	LR	0,A
	LR	A,IS
	AI	H'FF'		Back up 1
	LR	IS,A
	LR	A,S
	SR	4
	SR	1
	AS	0
	NS	3
	LR	3,A
	POP

*Subroutine used both by RBJ and RBN
RBJN	LR	A,S
	SL	4
	SL	1
	LR	0,A
	LR	A,IS
	AI	H'FF'
	LR	IS,A
	LR	A,S
	SR	4
	AS	0
	NS	3
	LR	3,A
	POP
*Subroutine to add to MOBILITY, and to store MOVE and FLAG bytes if necessary
STMV	LISU	3
	LISL	4		To MOVE byte
	LR	A,3		GET newly computed MOVE byte
	LR	0,A
	PI	CAQ		Count its bits
	AS	2		Add earlier counts
	LR	2,A		and store
	LR	A,S		Has one been stored?
	NS	S		To set status byte
	BNZ	STM2
	LIS	4
	ADC
	LR	A,3
	LR	I,A		Store MOVE and index to FLAG
	ST			Also put it in RAM record
	LR	A,4		Get the byte pointer
	SL	1
	SL	1
	LR	S,A		Save without indexing
	LR	A,7
	NI	3		Save the direction bits
	AS	S
	LR	I,A		Now we can index
	ST			Also put this into RAM
	LR	A,7
	SR	4		Extract the Jump flag
	NI	1		Delete any extraneous data
	AM			Add it to RAM (piece count in 1 thru 7)
STM2	POP
* NEXT  FIND  RFJ  LFJ  RBJ  LBJ  JUMT  AFT  MAKE  RARA

NEXT	LR	A,S		Get FLAG byte
	NI	7
	AI	1
	LR	S,A		Updated FLAG put back temporarily
	NI	7
	BZ	AFT
	LR	7,A		FLAG less J bit
	SR	1
	SR	1
	LR	4,A
	LR	A,7
	NI	3
	LR	5,A
	LR	A,S
	XS	7
	BNZ	NEX2
	LR	A,7
	AI	H'10'
NEX2	DCI	RFJ
	ADC
	LM
	DCI	JTAB
	ADC
	LR	Q,DC
	LR	PO,Q
JTAB	DC	0
	DC	(LFJ-RFJ)
	DC	(RBJ-RFJ)
	DC	(RFN-RFJ)
	DC	(LFN-RFJ)
	DC	(RBN-RFJ)
	DC	(LBN-RFJ)
FIND	LISU	2
	LISL	0		Start with byte 0
	CLR
	LR	2,A		Used to accumulate mobility count by STMV
*Look for jump moves first
	LIS	0
	LR	4,A		Used to distinguish byte
RFJ	PI	GMEN
	PI	FKT		Are there forward moving pieces?
	PI	FJET		Are jump moves in this direction posible?
	SR	1
	NI	H'77'		Save 6 particular bits only
	NS	3
	LR	3,A
	LR	A,IS
	AI	2		(remember displacement)
	LR	IS,A
	LISU	3		This gets us to the right KING byte
	PI	RFJN		This returns the RFJ byte in 3 and sets STATUS
	BZ	LFJ
	LI	H'10'		The RFJ direction and J indicator
	LR	7,A
	PI	STMV		Store MOVE ans FLAG if MOVE found and set STATUS
	BZ	LFJ		Move already stored so must be going ahead
	LR	A,6		This is H'FF' if going ahead
	XI	H'FF'
	BNZ	JUMF		Stop after finding a valid MOVE byte
LFJ	PI	GMEN
	PI	FKT
	PI	FJET		Are jump moves in this direction posible?
	SL	1
	NI	H'EE'		Save 6 particular bits only
	NS	3
	LR	3,A
	LR	A,IS
	AI	2		(remember displacement)
	LR	IS,A
	LISU	3		This gets us to the right KING byte
	PI	LFJN		This returns the LFJ byte in 3
	BZ	RBJ
	LI	H'11'		The LFJ direction and J indicator
	LR	7,A
	PI	STMV
	LR	A,6		This is H'FF' if going ahead
	XI	H'FF'
	BNZ	JUMF		Stop after finding a valid MOVE byte
RBJ	PI	GMEN
	PI	BKT
	PI	BJET
	SR	1
	NI	H'77'		Save 6 particular bits only
	NS	3
	LR	3,A
	LR	A,IS
	AI	2		(remember displacement)
	LR	IS,A
	LISU	3		This gets us to the right KING byte
	PI	RBJN		This returns the RBJ byte in 3
	BZ	LBJ
	LI	H'12'		The RBJ direction and J indicator
	LR	7,A
	PI	STMV
	LR	A,6		This is H'FF' if going ahead
	XI	H'FF'
	BNZ	JUMF		Stop after finding a valid MOVE byte
LBJ	PI	GMEN
	PI	BKT
	PI	BJET
	SL	1
	NI	H'EE'		Save 6 particular bits only
	NS	3
	LR	3,A
	LR	A,IS
	AI	2		(remember displacement)
	LR	IS,A
	LISU	3		This gets us to the right KING byte
	PI	LBJN		This returns the RBJ byte in 3
	BZ	JUMT
	LI	H'13'		The RBJ direction and J indicator
	LR	7,A
	PI	STMV
	LR	A,6		This is H'FF' if going ahead
	XI	H'FF'
	BZ	JUMT		Stop after finding a valid MOVE byte
JUMF	JMP	SELE		Go to SELECT on finding a move
JUMT	LR	A,4
	AI	1
	NI	3
	LR	4,A
	BNZ	RFJ		Go round again for next byte
	LISU	3
	LISL	4
	LR	A,S
	NS	S
	BZ	AFT
	JMP	SELE		Jump move found on initial FIND
*No moves found so time to back up
AFT	LR	DC,H
	LI	H'F'		Get to SCORE
	ADC
	LM
	LR	0,A		The current board score
	LR	A,11		Where are we?
	CI	H'10'
	BZ	MAKE		Time to make move
	CI	H'20'
	BP	AFT1		Can't α-β prune if this near the start
	LI	H'DE'
	ADC
	LR	A,0
	CM	
	BP	AFT3		Back 2 boards (α-β pruning)
AFT1	LR	DC,H
	LR	A,0
	COM	
	AI	1		Change sign of score
	LR	0,A
	LI	H'FF'
	ADC
	LR	A,0
	CM
	BP	AFT2
	LI	H'FF'
	ADC
	LR	A,0
	ST
	LI	H'20'		Set up to move block 2 back to block 0
	LR	11,A
	LR	DC,H
	LI	H'10'
	LR	0,A
	PI	RARA		To move board from block 2 to block 0
	LI	H'10'
	LR	11,A
	LR	DC,H
AFT2	JMP	SELE
	
MAKE


*Subroutine to move a block of data back 2 levels
Used in AFT but will also be used in handling non-forked double jumps
RARA	LM
	LR	1,A
	LI	H'DF'
	AS	11
	LR	DC,H
	LR	A,1
	ST
	LI	H'1F'
	AS	11
	LR	DC,H
	DS	0
	BNZ	RARA
	POP
* RFN  LFN  RBN  LBN  NORT

RFN	PI	GMEN
	PI	FKT
	BZ	RBN
	LR	A,I		Just to index
	LR	A,I		Just to index
	LISU	4
	PI	RFJN
	BZ	LFN
	CLR
	LR	7,A
	PI	STMV
	LR	A,6
	XI	H'FF'
	BNZ	NORF
LFN	PI	GMEN
	PI	FKT
	BZ	RBN
	LR	A,I		Just to index
	LR	A,I		Just to index
	LISU	4
	PI	LFJN
	BZ	RBN
	LIS	1
	LR	7,A
	PI	STMV
	LR	A,6
	XI	H'FF'
	BNZ	NORF
RBN	PI	GMEN
	PI	BKT
	BZ	NORT
	LISU	4
	PI	RBJN
	BZ	NORT
	LIS	2
	LR	7,A
	PI	STMV
	LR	A,6
	XI	H'FF'
	BNZ	NORF
LBN	PI	GMEN
	PI	BKT
	BZ	NORT
	LISU	4
	PI	LBJN
	BZ	NORT
	LIS	3
	LR	7,A
	PI	STMV
	LR	A,6
	XI	H'FF'
	BZ	NORT
NORF	JMP	SELE
NORT	LR	A,4
	AI	1
	NI	3
	LR	4,A
	BNZ	RFN		Go round again for next byte
	LR	A,2		Get mobility count
	NS	2
	BZ	NRT1		Woops, no moves found
	AI	H'FF'		Subtract 1 to conserve spase
	CI	7
	BP	NRTX
	LI	7		Limit it to 3 bits
NRTX	SL	4
	SL	1		Shift left by 5
	LISU	3		Going ahead so we may have found one earlier
	LISL	5
	AS	A,S
	JMP	FORE
NRT1	JMP	AFT		All moves at this level exhausted
**** SAVE MOBILITY HERE

	LR	A,****		But is it time to stop
***WE MUST DECIDE WHERE STOPPING LEVEL IS KEPT
	AS	11
*****We will assume it is saved in COM form
	BP	EVAL		**** We may have to do some things first
	JMP	SELE
* SELECT  SELE

*SELECT branches to NEXT if MOVE is empty, or it extracts the rightmost
bit from the MOVE byte in RAM, storing the extracted bit in SC 6, puts the
FLAG byte in SC 7, the byte number in 4, and the J and direction bits in 5.
and proceeds to make the selected move.
SELECT	LR	DC,H		Load DC  with starting location for current ply
	PI	RASC		Get board data into Scratchpad
SEL2	LR	DC,H
	LIS	A,4		To get MOVE byte
	ADC
	LM
	LR	0,A		Save it temporarily
	NS	0		To set status byte
	BNZ	SEL3
	JMP	NEXT		To get next MOVE byte
SEL3
	LI	H'FE'
	ADC			Get back to move byte
	LR	A,0
	AI	H'FF'		Really subtracting 1
	NS	0		Remove right-most on-bit
	ST			Put remaining bits back (and index to FLAG byte)
	XS	0		This gets the extracted bit
	LR	6,A		Save it in 6
	LM
	LR	5,A
	SR	1
	SR	1
	NI	3		Separate the byte indicator part
	LR	4,A		Save it in 4
	LM			Get the Jump flag
	NI	1
	SL	4
	AS	5
	LR	5,A		Save them in 5
	
*Now process ACTIVE and KINGS for source deletion
DELE	PI	GMEN
	XS	6		Delete moving piece
	LR	S,A		from byte
	LISU	3		To get to corresponding KING byte
	LR	A,S
	NS	6		Was the piece a king?
	BZ	DEL2
	XS	S		If it was delete king bit
	LR	S,A
	LI	7		Non-zero in 2 for king 
DEL2	LR	2,A		Save as a flag for kind of piece moving
*Now locate captured piece if jump or find destination in normal move
	LR	6		Recall MOVE bit
	SR	4
	BZ	INRH		Bit was in right half of byte
INLH	LR	3,A		Save partially shifted MOVE bit
	LR	A,5		Get direction
	NI	1		To test right-most bit
	BZ	INL2		RF or LB move where 4 shift is correct
	LR	A,3
	SR	1		LF and LB require an additional shift
	LR	3,A
INL2	LR	A,5		Now test for fore or aft
	NI	2
	BZ	BOTH		Bit was off so forward move and no byte shift needed
	LR	A,D		Only to decrement ISAR
INL3	BR	BOTH

INRH	LR	6		Get MOVE bit again
	SL	4		Left shift if in right half
	LR	3,A		Save partially shifted MOVE bit
	LR	A,5		Get direction
	NI	1
	BNZ	INR2		LF or RB wwhere 4 shift is correct
	LR	A,3
	SL	1		RF and RB require an additional shift
	LR	3,A
INR2	LR	A,5		Now test fore and aft
	NI	2
	BNZ	BOTH
	LR	A,I		Only to increment ISAR
*Now we are ready to decide if jump or not
BOTH	CHR
	LR	0,A		Used temporarily to accumulate piece debit
	LR	A,5		Now is this a jump or a normal move?
	SR	4
	BZ	NORM		Normal move case
	LR	A,S		Get King Byte corresponding to captured piece
	NS	3		Was piece a king?
	BZ	BOT2		No
	XS	3		Delete it
	LR	S,A		And replace byte
	LR	A,0
	INC			Count 1 extra for king
	LR	0,A
BOT2	LIS	2
	AS	0		Count 2 for piece capture
	LR	0,A
	LISU	2		Get back to right buffer for ACTIVE and PASSIVE
	LR	A,IS
	AI	4		Increment to PASSIVE byte
	LR	IS,A
	LR	A,S		Get appropiate PASSIVE byte
	XS	3		Delete capture
	LR	S,A		And return byte
	LISU	2		Back to moved-from location
	LISL	0
	LR	A,IS
	AS	4
	LR	IS,A
	LR	A,5		Get direction
	NI	1		Test for right or left
	BZ	BOT3
	LR	A,6
	SR	1
	BZ	BOT4
BOT3	LR	A,6
	SL	1
BOT4	LR	3,A		Save displaced bit in 3
	LR	A,5
	NI	2		Test for fore or aft
	BZ	BOT5		Fore move
	LR	A,D		Decrement ISAR
	LR	A,2		Was the piece a king?
	NS	2
	BNZ	BOT6		Yes, so not necessary to test for a promotion
	LR	A,IS
	CI	H'14'		Is this WHITE's king row
	BNZ	BOT6		No
	BR	BOT7
BOT5	LR	A,I		Increment ISAR
	LR	A,2
	NS	2
	BNZ	BOT6
	LR	A,IS
	CI	H'17'		Is this BLACK's king row
	BNZ	BOT6		No
BOT7	LIS	7
	LR	2,A		It is so promote piece
	LR	A,0
	INC			Add 1 to debit account
	LR	0,A
BOT6	LR	A,S		Now get right byte
	AS	3		Insert piece
	LR	S,A
	LR	A,2		Get king indicator
	NS	2
	BZ	BOT9		Not a king
BOT8	LR	A,IS
	AI	4		Go to correct king byte
	LR	A,S
	AS	3
	LR	S,A
BOT9	LISU	3
	LISL	2
	LR	A,0
	SL	1		Remember piece debit is displaced 1 to left
	AS	S
	LR	S,A
	JMP	FORE
* NORM  FORE

*Now make normal move
NORM	LISU	2		Get back to Active pieces
	LR	A,S
	AS	3
	LR	S,A		Put in moved piece
	LR	A,2		Was it a king
	NI	S
	BNZ	NOR6		Yes so don't promote
	LR	A,5
	NI	2		Test for direction
	BZ	NOR4		Black is active
	LR	A,IS
	CI	H'14'
	BNZ	NOR6
	BR	NOR5
NOR4	LR	A,IS
	CI	H'17'
	BNZ	NOR6
NOR5	LR	A.0
	INC
	LR	A,0
	LIS	7
	LR	2,A
NOR6	LISU 	3		Now get to king byte
	LR	A,2		This was set to non-zero if King moving
	NI	7
	BZ	NOR7		Not a king
	LR	A,S		Get corresponding king byte for destination
	AS	3		Insert moved king
	LR	S,A		And replace byte
NOR7	JMP	BOT9

FORE
	LR	DC,H
	LI	H'10'
	ADC			To next board record
	LR	H,DC
	PI	SCRA		Save newly created board record
	LR	A,8
	COM			Reverse color
	LR	8,A
	PI	RASC		Get correct board into SC
	LI	H'FF'
	LR	6,A		So all moves will be found
	JMP	FIND
* EVAL

EVAL	LR	DC,H		Make sure this is correct
	LIS	5		To get current board mobility
	ADC
	LISU	3
	LISL	1		To  get previous board mobility
	LR	A,11		To find ply
	SR	4
	COM			Make it negative 
	AI	3		and reduce its magnitude
	LR	5,A		Save it, we'll need it later
	LR	A,I
	SR	4
	LR	3,A
	LM			Now the current board
	SR	4
	COM
	AI	1		Make it a true negation
	AS	3
	LR	3,A		Mobility debit for ACTIVE
	LR	A,I		Now for the piece advantage term
	SR	1		Remember displacement
	LR	2,A
	LM
	SR	1
	LR	0,A
	LR	1,A
	COM
	AI	1		Make it a true negation
	AS	2
	LR	4,A		Save for its sign
	BZ	EVA4		No material advantage
	BP	EVA2
	COM		
	AI	1		Make it a true negation
	LR	1,A
	LR	A,0
	LR	2,A
EVA2	LR	A,2
	AI	2		Increase larger by 2
	LR	2,A	
	PI	MPYR		Multiply  2 by 1 and limit product to 30
	LR	A,0
	SL	1
	SL	1		Shift left by 2
	AS	5		Subtract ply for early exploitation of advantage
	LR	0,A
	LR	A,4
	NS	4
	LR	A,0
	BM	EVA3
	COM
	AI	1		Make it a true negation
	LR	0,A		Score with sign
EVA3	LR	A,0
EVA4	LR	1,A		Save it
	AS	3		Add in mobility difference.
	LR	3,A		And save in 3 (in COM form)
	AS	S		This is the score for 2 boards earlier
	BM	EVAL6		Back up 2 levels (α-β pruning)
	LR	DC,H		Otherwise back 1 level
	LR	H'F0'
	ADC
	LR	H,DC
	LIS	H'F'
	ADC
	LR	A,3
	CM	
	BP	EVA5
	LR	H'FF'
	ADC			Get back to right byte
	LR	A,3
	ST			Store new value
EVA5	JMP	SELE
EVA6	LIS	H'E0'		Back 2 levels
	LR	DC,H
	ADC
	LR	H,DC
	JMP	SELE
* SQIN  SQOU  MVIN 

*Subroutine to accept a square number in standard checker notation in SC 1 and
to return a byte number in SC 2 and a MOVE byte (with 1 bit on) in SC 3.
SQIN	LR	A,1
	AI	H'FF'
	LR	1,A
	SR	1
	SR	1
	SR	1
	LR	2,A		This is the byte number
	LR	A,1
	NI	7
	LI	H'80'
	BR	SQI2
SQI1	LR	A,3
	SR	1
SQI2	LR	3,A
	LR	A,1
	AI	H'FF'
	LR	1,A
	BNZ	SQI1
	POP

*Subroutine to accept a byte number in 2 and a MOVE byte in 3 and to return
a square number in standard checker notation in 1.

SQOU	LR	A,2
	SL	1
	SL	1
	SL	1		Multiiply by 8
	LR	1,A
SQO1	LR	A,1
	AI	1
	LR	1,A
SQO2	LR	A,3
	SL	1
	LR	3,A
	BP	SQO1
	POP

*Subroutine to analyse an input move (received as two numbers in 1 and 2)
and to verify that the move is acceptable.

The general scheme is to verify certain aspects of the proposed move and
to extract the direction indicator from it.  A call to FIND will then verify
that this move is indeed possible.

****THIS CODE IS MUCH TOO LONG. THERE MUST BE A BETTER WAY.
**** We must also decide on the number of messages that we may want to
generate.  This code assumes only three: 1) "You must JUMP", 2) "Try again",
or perhaps "Illegal move" and 3) "O.K.".

MVIN	CLR
	LR	11,A
	LR	DC,H
	LI	H'E'
	ADC
	LM
	NI	1		Extract J
	LR	3,A		Save as required Jump flag
	LR	A,1
	COM
	AI	1
	AS	2
	LR	4,A		Save for front or back move signal
	BP	MVI2
	COM
	AI	1
MVI2	LR	5,A		Save magnitude of difference
	CI	6
	BM	MVJ1		Seems to be a jump move
	LR	A,1
	NI	1
	BZ	MVN2		Normal move called for
	JMP	ERR1		An error, Jump is required
MVN2	CI	3
	BZ	MVN3		Must be RF or LB
	CI	5
	BZ	MVN4		Must be LF or RB
	CI	4
	BZ	MVN5		Can not decide yet
	JMP	ERR2		An error, normal move required
MVN5	LR	A,1
	AI	H'FF'		Subtract 1
	NI	4		Which half of byte
	BNZ	MVN4		Must be LF or RB
MVN3	LR	A,4		A RF or LB 
	NS	4
	BM	MVN6
	CLR			RF
	BR	MVI3
MVN6	LI	3		LB
	BR	MVI3
MVN4	LR	A,4
	NS	4
	BM	MVN7
	LI	1		LF
	BR	MVI3
MVN7	LI	2		RB
	BR	MVI3

MVJ1	LR	A,1
	NI	1
	BNZ	MVJ2
	JMP	ERR2		An error, normal move required
MVJ2	LR	A,5
	CI	7		
	BZ	MVJ3		It's either RFJ or LBJ
	CI	9		
	BZ	MVJ5		It's either LFJ or RBJ
	JMP	ERR1		An error, jump is required
MVJ3	LR	A,4
	NS	4
	BM	MVJ4
	LI	H'10'		RFJ
	BR	MVI3
MVJ4	LI	H'13'		LBJ
	BR	MVI3
MVJ5	LR	A,4
	NS	4
	BM	MVJ6
	LI	H'11'		LFJ
	BR	MVI3
MVJ6	LI	H'12'		RBJ
	BR	MVI3
MVI3	LR	0,A		Save temporarily
**** Now we must fix matters so that FIND may be called to see if this is
a legel move
**** Then we do the following

	PI	SQIN		Get the byte number into 2 and the move byte into 3
	LR	DC,H
	PI	RASC
	LR	DC,H
	LR	A,3
	LR	6,A

	LR	A,2
	SL	1
	SL	1
	AS	0		THIS HAS THE JUMP BIT IN H'10'

**** This has the JUMP bit in the original FLAG byte
**** We are about ready to enter SELECT at about DELE but some fixing is necessary